In both i386 and x86-64 Linux, using a static variable (and thus
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 20 Apr 2006 13:10:35 +0000 (14:10 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 20 Apr 2006 13:10:35 +0000 (14:10 +0100)
having the potential of missing synchronization there,
as I suspect exists in native Linux) is not needed with the hypercall
approach. In the hypervisor, the patch adds the
needed synchronization.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c
linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
xen/arch/x86/io_apic.c

index 47edb0524be37bda761d81274486b697255221b9..88a9f2f6f6b0b3c0a73523c87ea9ec8c43913ba7 100644 (file)
@@ -1205,7 +1205,6 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly; /* = { FIRST_DEVICE_VECTOR , 0 }; *
 
 int assign_irq_vector(int irq)
 {
-       static int current_vector = FIRST_DEVICE_VECTOR;
        physdev_op_t op;
 
        BUG_ON(irq >= NR_IRQ_VECTORS);
@@ -1216,13 +1215,12 @@ int assign_irq_vector(int irq)
        op.u.irq_op.irq = irq;
        if (HYPERVISOR_physdev_op(&op))
                return -ENOSPC;
-       current_vector = op.u.irq_op.vector;
 
-       vector_irq[current_vector] = irq;
+       vector_irq[op.u.irq_op.vector] = irq;
        if (irq != AUTO_ASSIGN)
-               IO_APIC_VECTOR(irq) = current_vector;
+               IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
 
-       return current_vector;
+       return op.u.irq_op.vector;
 }
 
 #ifndef CONFIG_XEN
index fd72947df79165eb758575256400dec225d37a47..d71120093e7a9f57b9413271f8e7693a2a8adeb6 100644 (file)
@@ -869,7 +869,6 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
 
 int assign_irq_vector(int irq)
 {
-       static int current_vector = FIRST_DEVICE_VECTOR;
        physdev_op_t op;
   
        BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
@@ -880,13 +879,12 @@ int assign_irq_vector(int irq)
        op.u.irq_op.irq = irq;
        if (HYPERVISOR_physdev_op(&op))
                return -ENOSPC;
-       current_vector = op.u.irq_op.vector;
 
-       vector_irq[current_vector] = irq;
+       vector_irq[op.u.irq_op.vector] = irq;
        if (irq != AUTO_ASSIGN)
-               IO_APIC_VECTOR(irq) = current_vector;
+               IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
 
-       return current_vector;
+       return op.u.irq_op.vector;
 }
 
 extern void (*interrupt[NR_IRQS])(void);
index 4b7b1c51264a6ce11322adbb459a024bf49cd7c3..4d74e1900ce4132ae36639b4f39549ec516b797c 100644 (file)
@@ -48,6 +48,7 @@ atomic_t irq_mis_count;
 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 
 static DEFINE_SPINLOCK(ioapic_lock);
+static DEFINE_SPINLOCK(vector_lock);
 
 int skip_ioapic_setup;
 
@@ -661,11 +662,17 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
 
 int assign_irq_vector(int irq)
 {
-    static int current_vector = FIRST_DYNAMIC_VECTOR, offset = 0;
+    static unsigned current_vector = FIRST_DYNAMIC_VECTOR, offset = 0;
+    unsigned vector;
 
     BUG_ON(irq >= NR_IRQ_VECTORS);
-    if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
+    spin_lock(&vector_lock);
+
+    if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
+        spin_unlock(&vector_lock);
         return IO_APIC_VECTOR(irq);
+    }
+
 next:
     current_vector += 8;
 
@@ -679,16 +686,21 @@ next:
 
     if (current_vector > LAST_DYNAMIC_VECTOR) {
         offset++;
-        if (!(offset%8))
+        if (!(offset%8)) {
+            spin_unlock(&vector_lock);
             return -ENOSPC;
+        }
         current_vector = FIRST_DYNAMIC_VECTOR + offset;
     }
 
-    vector_irq[current_vector] = irq;
+    vector = current_vector;
+    vector_irq[vector] = irq;
     if (irq != AUTO_ASSIGN)
-        IO_APIC_VECTOR(irq) = current_vector;
+        IO_APIC_VECTOR(irq) = vector;
+
+    spin_unlock(&vector_lock);
 
-    return current_vector;
+    return vector;
 }
 
 static struct hw_interrupt_type ioapic_level_type;